package com.carkeeper.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carkeeper.dto.BillDTO;
import com.carkeeper.dto.StoreDTO;
import com.carkeeper.mapper.StoreDetailMapper;
import com.carkeeper.mapper.StoreMapper;
import com.carkeeper.mapper.UserMapper;
import com.carkeeper.pojo.StoreDetailPO;
import com.carkeeper.pojo.StorePO;
import com.carkeeper.pojo.StoreUserPO;
import com.carkeeper.service.BillFeign;
import com.carkeeper.service.StoreService;
import com.carkeeper.utils.ObjectUtil;
import com.carkeeper.vo.Pager;
import com.carkeeper.vo.StoreQueryParam;
import com.carkeeper.vo.StoreVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class StoreServiceImpl implements StoreService {
    @Autowired
    public StoreMapper storeMapper;
    @Autowired
    public StoreDetailMapper storeDetailMapper;
    @Autowired
    public UserMapper userMapper;

    @Autowired
    public RedisTemplate redisTemplate;

    @Autowired
    private BillFeign billFeign;

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
    public boolean create(StoreVO storeVO) {

        Long code = redisTemplate.opsForValue().increment("code");
        if (code < 100000) {
            redisTemplate.opsForValue().set("code", 100000);
            code = redisTemplate.opsForValue().increment("code");
        }

        //主体编码
        storeVO.setCode(code + "");
        // 默认为未审核
        storeVO.setAuditStatus(0);
        // 默认为正常状态
        storeVO.setStatus(1);

        StorePO storePO = new StorePO();
        BeanUtils.copyProperties(storeVO, storePO);
        storeMapper.insert(storePO);

        StoreDetailPO storeDetailPO = new StoreDetailPO();
        BeanUtils.copyProperties(storeVO, storeDetailPO);
        storeDetailPO.setId(storePO.getId());

        int rows = storeDetailMapper.insert(storeDetailPO);
        return rows > 0;
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
    public boolean update(StoreVO storeVO) {

        int baseRows = 0;
        int detailRows = 0;

        StorePO storePO = new StorePO();
        BeanUtils.copyProperties(storeVO, storePO);
        // 需要更新基础信息时再更新基础信息表
        if (!ObjectUtil.fieldsIsNull(storePO, Arrays.asList("id"))) {
            baseRows = storeMapper.updateById(storePO);
        }

        StoreDetailPO storeDetailPO = new StoreDetailPO();
        BeanUtils.copyProperties(storeVO, storeDetailPO);
        // 需要更新详细信息时再更新详细信息表
        if (!ObjectUtil.fieldsIsNull(storeDetailPO, Arrays.asList("id"))) {
            detailRows = storeDetailMapper.updateById(storeDetailPO);
        }
        return baseRows > 0 || detailRows > 0;
    }

    @Override
    public boolean delete(Long id) {
        return storeMapper.deleteById(id) > 0;
    }

    @Override
    public Pager<StoreDTO> queryPageByParam(StoreQueryParam queryParam) {
        if (queryParam.getPage() == null) {
            queryParam.setPage(1);
        }
        if (queryParam.getPageSize() == null) {
            queryParam.setPageSize(10);
        }

        Page<StorePO> page = new Page<>(queryParam.getPage(), queryParam.getPageSize());
        LambdaQueryWrapper<StorePO> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(queryParam.getSimpleName())) {
            queryWrapper.like(StorePO::getSimpleName, queryParam.getSimpleName());
        }
        if (StringUtils.isNotEmpty(queryParam.getCode())) {
            queryWrapper.like(StorePO::getCode, queryParam.getCode());
        }
        if (StringUtils.isNotEmpty(queryParam.getProvince())) {
            queryWrapper.eq(StorePO::getProvince, queryParam.getProvince());
        }
        if (StringUtils.isNotEmpty(queryParam.getCity())) {
            queryWrapper.eq(StorePO::getCity, queryParam.getCity());
        }
        if (StringUtils.isNotEmpty(queryParam.getCounty())) {
            queryWrapper.eq(StorePO::getCounty, queryParam.getCounty());
        }
        if (StringUtils.isNotEmpty(queryParam.getContactPhone())) {
            queryWrapper.like(StorePO::getContactPhone, queryParam.getContactPhone());
        }
        if (queryParam.getIsChain() != null) {
            queryWrapper.eq(StorePO::getIsChain, queryParam.getIsChain());
        }
        if (queryParam.getStatus() != null) {
            queryWrapper.eq(StorePO::getStatus, queryParam.getStatus());
        }
        if (queryParam.getType() != null) {
            queryWrapper.eq(StorePO::getType, queryParam.getType());
        }

        if (queryParam.getAuditStatus() != null) {
            queryWrapper.eq(StorePO::getAuditStatus, queryParam.getAuditStatus());
        }
        queryWrapper.orderByAsc(StorePO::getCreateTime);

        IPage<StorePO> iPage = storeMapper.selectPage(page, queryWrapper);
        List<StoreDTO> storeDTOList = iPage.getRecords().stream().map(storePO -> {
            StoreDTO dto = new StoreDTO();
            BeanUtils.copyProperties(storePO, dto);
            Integer count = userMapper.selectCount(new LambdaQueryWrapper<StoreUserPO>().eq(StoreUserPO::getStoreId, storePO.getId()));
            dto.setHasEmployee(0);
            if (count > 0) {
                dto.setHasEmployee(1);
            }
            BigDecimal decimal = new BigDecimal(0);
            List<BillDTO> billDTOList = billFeign.findAll(storePO.getId(), 2);
            for (BillDTO billDTO : billDTOList) {
                if (billDTO.getPrice() != null) {
                    decimal = decimal.add(new BigDecimal(billDTO.getPrice()));
                }
            }
            decimal = decimal.divide(new BigDecimal(100));
            decimal = decimal.setScale(2, BigDecimal.ROUND_HALF_UP);
            dto.setBillMoney(decimal);
            return dto;
        }).collect(Collectors.toList());
        return new Pager<StoreDTO>(iPage.getTotal(), iPage.getSize(), iPage.getPages(), iPage.getCurrent(), storeDTOList);
    }

    @Override
    public StorePO queryById(Long id) {
        return storeMapper.selectById(id);
    }

    @Override
    public StoreDetailPO queryDetailsById(Long id) {
        return storeDetailMapper.selectById(id);
    }
}